#include <stdio.h>
#include <unistd.h>
#include <cstring>
#include <cerrno>
#include "EventPoller.h"

using namespace yazi::socket;

EventPoller::EventPoller(bool et) : m_et(et), m_epfd(0), m_maxconnections(0), m_events(NULL){

}

EventPoller::~EventPoller(){
    if(m_epfd > 0){
        ::close(m_epfd);
        m_epfd = 0;
    }
    if(m_events != NULL){
        delete [] m_events;
        m_events = NULL;
    }
}

bool EventPoller::create(int maxconnections){
    m_maxconnections = maxconnections;
    int epfd = ::epoll_create(maxconnections);
    if (epfd == -1){
        perror("epoll()");
        return false;
    }
    m_epfd = epfd;
    if (m_events != NULL)
    {
        delete [] m_events;
        m_events = NULL;
    }
    m_events = new struct epoll_event[1 + maxconnections];
}

bool EventPoller::add(int fd, void *ptr, uint32_t events){
    return ctrl(fd, ptr, events, EPOLL_CTL_ADD);
}
bool EventPoller::mod(int fd, void* ptr, uint32_t events){
    return ctrl(fd, ptr, events, EPOLL_CTL_MOD);
}
bool EventPoller::del(int fd, void *ptr, uint32_t events){
    return ctrl(fd, ptr, events, EPOLL_CTL_DEL);
}
int EventPoller::wait(int millseconds){
    int ret = ::epoll_wait(m_epfd, m_events, m_maxconnections + 1, millseconds);
    if(ret == -1){
        perror("epoll()");
        return -1;
    }
    return ret;
}

bool EventPoller::ctrl(int fd, void* ptr, uint32_t events, int op){
    struct epoll_event event;
    event.data.ptr = ptr;
    event.events = m_et ? events | EPOLLET : events;
    int ret = ::epoll_ctl(m_epfd, op, fd, &event);
    if (ret == -1)
    {
        perror("epoll_ctl()");
        return false;
    }
    return true;
}
